﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace HandleServer
{
    public class HandleServer
    {
        private TcpListener _listener;
        private readonly int _port;
        private readonly CancellationTokenSource _cts = new CancellationTokenSource();

        public HandleServer(int port)
        {
            _port = port;
        }

        public void Start()
        {
            _listener = new TcpListener(IPAddress.Any, _port);
            _listener.Start();
            Console.WriteLine($"Server started on port {_port}");
            AcceptClientsAsync();
        }

        private async void AcceptClientsAsync()
        {
            while (!_cts.IsCancellationRequested)
            {
                var client = await _listener.AcceptTcpClientAsync();
                Console.WriteLine($"Client connected: {client.Client.RemoteEndPoint}");
                _ = HandleClientAsync(client);
            }
        }

        private async System.Threading.Tasks.Task HandleClientAsync(TcpClient client)
        {
            var buffer = new byte[4096];
            var receiveBuffer = new List<byte>();

            try
            {
                using (var stream = client.GetStream())
                {
                    while (client.Connected && !_cts.IsCancellationRequested)
                    {
                        var bytesRead = await stream.ReadAsync(buffer, 0, buffer.Length, _cts.Token);
                        if (bytesRead == 0) break;

                        // 将新数据加入缓冲区
                        receiveBuffer.AddRange(new ArraySegment<byte>(buffer, 0, bytesRead));

                        // 解析数据包
                        while (true)
                        {
                            var parseResult = TryParsePacket(receiveBuffer.ToArray(), out var packet, out var packetSize);
                            if (!parseResult) break;

                            // 处理有效数据包
                            ProcessPacket(packet, stream);

                            // 从缓冲区移除已处理数据
                            receiveBuffer.RemoveRange(0, packetSize);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Client error: {ex.Message}");
            }
            finally
            {
                client.Close();
                Console.WriteLine($"Client disconnected: {client.Client.RemoteEndPoint}");
            }
        }


        private bool TryParsePacket(byte[] buffer, out TcpPacket packet, out int packetSize)
        {
            packet = null;
            packetSize = 0;

            // 最小包长度检查 (包头2 + 长度4 + 命令1 + 包尾2 = 9字节)
            if (buffer.Length < 9) return false;

            // 查找包头
            int startIndex = FindHeaderIndex(buffer);
            if (startIndex == -1) return false;

            // 提取数据长度 (大端序)
            byte[] lengthBytes = new byte[4];
            Array.Copy(buffer, startIndex + 2, lengthBytes, 0, 4);
            if (BitConverter.IsLittleEndian) Array.Reverse(lengthBytes);
            uint dataLength = BitConverter.ToUInt32(lengthBytes, 0);

            // 计算完整包长度
            int totalLength = startIndex + 9 + (int)dataLength;
            if (buffer.Length < totalLength) return false;

            // 验证包尾
            byte[] footer = new byte[2];
            Array.Copy(buffer, totalLength - 2, footer, 0, 2);
            if (!footer.SequenceEqual(TcpPacket.Footer)) return false;

            // 提取有效数据
            byte[] packetData = new byte[totalLength - startIndex];
            Array.Copy(buffer, startIndex, packetData, 0, packetData.Length);

            // 反序列化
            try
            {
                packet = TcpPacket.Deserialize(packetData);
                packetSize = packetData.Length;
                return true;
            }
            catch
            {
                return false;
            }
        }


        private int FindHeaderIndex(byte[] buffer)
        {
            for (int i = 0; i <= buffer.Length - 2; i++)
            {
                if (buffer[i] == 0xFF && buffer[i + 1] == 0xFF)
                {
                    return i;
                }
            }
            return -1;
        }

        private void ProcessPacket(TcpPacket packet, NetworkStream stream)
        {
            Console.WriteLine($"Received command: 0x{packet.Command:X2}, Data: {Encoding.UTF8.GetString(packet.Data)}");

            // 示例回复逻辑
            var response = new TcpPacket
            {
                Command = 0xA0,
                Data = Encoding.UTF8.GetBytes("Server received: " + DateTime.Now.ToString("HH:mm:ss"))
            };
            SendPacket(response, stream);
        }

        private async void SendPacket(TcpPacket packet, NetworkStream stream)
        {
            try
            {
                byte[] data = packet.Serialize();
                await stream.WriteAsync(data, 0, data.Length, _cts.Token);
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Send error: {ex.Message}");
            }
        }

        public void Stop()
        {
            _cts.Cancel();
            _listener.Stop();
            Console.WriteLine("Server stopped");
        }
    }
}
